#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <stack>
#include <queue>
#include <Windows.h>
using namespace std;
typedef struct _Node
{
int data;
struct _Node *left;
struct _Node *right;
int bf; //平衡因子
_Node()
{
data = 0;
left = NULL;
right = NULL;
bf = 0;
}
}Node, *_PNode;
//******************************************AVL**********************************************begin
//参考 维基百科 AVL : http://zh.wikipedia.org/wiki/AVL%E6%A0%91
// http://www.cnblogs.com/abatei/archive/2008/11/17/1335031.html
//右旋
_PNode AVLLLTree(_PNode pNode)
{
_PNode pNewNode = pNode->left;
pNode->left = pNewNode->right;
pNewNode->right = pNode;
if (pNewNode->bf == 1)
{
pNode->bf = 0;
pNewNode->bf = 0;
}
else
{
pNode->bf = 1;
pNewNode->bf = -1;
}
return pNewNode;
}
//左旋
_PNode AVLRRTree(_PNode pNode)
{
_PNode pNewNode = pNode->right;
pNode->right = pNewNode->left;
pNewNode->left = pNode;
if (pNewNode->bf == -1)
{
pNode->bf = 0;
pNewNode->bf = 0;
}
else
{
pNode->bf = -1;
pNewNode->bf = 1;
}
return pNewNode;
}
//先右旋再左旋
_PNode AVLLRTree(_PNode pNode)
{
_PNode pLeft = pNode->left;
_PNode pNewNode = pLeft->right;
pLeft->right = pNewNode->left;
pNode->left = pNewNode->right;
pNewNode->left = pLeft;
pNewNode->right = pNode;
switch (pNewNode->bf )
{
case 1:
pLeft->bf = 0;
pNode->bf = -1;
break;
case -1:
pLeft->bf = 1;
pNode->bf = 0;
break;
}
pNewNode->bf = 0;
return pNewNode;
}
//先左旋再右旋
_PNode AVLRLTree(_PNode pNode)
{
_PNode pRight = pNode->right;
_PNode pNewNode = pRight->left;
pRight->left = pNewNode->right;
pNode->right = pNewNode->left;
pNewNode->left = pNode;
pNewNode->right = pRight;
switch (pNewNode->bf)
{
case 1:
pNode->bf = 0;
pRight->bf = -1;
break;
case -1:
pNode->bf = 1;
pRight->bf = 0;
break;
}
pNewNode->bf = 0;
return pNewNode;
}
_PNode pAvlRoot = NULL; //AVL的根节点
stack<_PNode> sAvl; //保存从根节点到插入点的路径节点
bool AVLRotateTree(_PNode pNode, int bf)
{
bool bTallChange = true;
_PNode pChild;
_PNode pNewNode;
if (2 == bf)
{
pChild = pNode->left;
if (1 == pChild->bf)
{
pNewNode = AVLLLTree(pNode);
}
else if (-1 == pChild->bf)
{
pNewNode = AVLLRTree(pNode);
}
else
{
pNewNode = AVLLLTree(pNode);
bTallChange = false;
}
}
else if (-2 == bf)
{
pChild = pNode->right;
if (1 == pChild->bf)
{
pNewNode = AVLRLTree(pNode);
}
else if (-1 == pChild->bf)
{
pNewNode = AVLRRTree(pNode);
}
else
{
pNewNode = AVLRRTree(pNode);
bTallChange = false;
}
}
if (!sAvl.empty())
{
_PNode pParent = sAvl.top();
if (pParent->data > pNewNode->data)
{
pParent->left = pNewNode;
}
else if (pParent->data < pNewNode->data)
{
pParent->right = pNewNode;
}
}
else
{
pAvlRoot = pNewNode;
}
return bTallChange;
}
//插入节点
void AVLInsertNode(int key)
{
if (BSTSearch(pAvlRoot, key)) //找到,不能插入直接返回
{
return;
}
_PNode pNode = new Node;
pNode->data = key;
if (NULL == pAvlRoot)
{
pAvlRoot = pNode;
return;
}
while (!sAvl.empty()) //清空栈
{
sAvl.pop();
}
_PNode p = pAvlRoot;
while (NULL != p)
{
sAvl.push(p);
if (key < p->data)
{
p = p->left;
}
else if (key > p->data)
{
p = p->right;
}
}
_PNode pre = sAvl.top();
if (key < pre->data)
{
pre->left = pNode;
}
else if (key > pre->data)
{
pre->right = pNode;
}
int bf;
while (!sAvl.empty())
{
pre = sAvl.top();
sAvl.pop();
bf = (pre->data > key) ? 1 : -1;
pre->bf += bf;
bf = pre->bf;
if (bf == 0)
{
break;
}
else if (2 == bf || -2 == bf)
{
AVLRotateTree(pre, bf);
break;
}
}
}
//删除节点
void AVLRemoveNode(int key)
{
_PNode pNode = pAvlRoot;
while (!sAvl.empty())
{
sAvl.pop();
}
while (NULL != pNode)
{
if (key < pNode->data)
{
sAvl.push(pNode);
pNode = pNode->left;
}
else if (key > pNode->data)
{
sAvl.push(pNode);
pNode = pNode->right;
}
else
{
_PNode pPreNode = sAvl.top();
if (NULL == pNode->left || NULL == pNode->right) //3、该节点只有一条子树
{
if (NULL != pNode->left)
{
if (pNode == pAvlRoot)
{
pAvlRoot = pNode->left;
}
else if (pPreNode->left == pNode)
{
pPreNode->left = pNode->left;
}
else
{
pPreNode->right = pNode->left;
}
}
else
{
if (pNode == pAvlRoot)
{
pAvlRoot = pNode->right;
}
else if (pPreNode->left == pNode)
{
pPreNode->left = pNode->right;
}
else
{
pPreNode->right = pNode->right;
}
}
}
else //4、该节点有左右子树
{
_PNode pPre = pNode;
sAvl.push(pNode);
_PNode pSearch = pNode->right;
while (NULL != pSearch->left) //5、找该节点右子树的最小值,即真正删除的点
{
sAvl.push(pSearch);
pPre = pSearch;
pSearch = pSearch->left;
}
sAvl.pop(); //删除的点没用,将删除的点弹栈
pNode->data = pSearch->data;
if (pPre->left == pSearch)
{
pPre->left = pSearch->right;
}
else
{
pPre->right = pSearch->right;
}
}
int bf;
while (!sAvl.empty())
{
pPreNode = sAvl.top();
sAvl.pop();
bf = (pPreNode->data > key) ? -1 : 1;
pPreNode->bf += bf;
bf = pPreNode->bf;
if (0 != bf)
{
if (1 == bf || -1 == bf || !AVLRotateTree(pPreNode, bf))
{
break;
}
}
}
break;
}
}
}
//******************************************AVL***********************************************end